package com.asa.physics;

import com.asa.hutils.MathHUtils;
import com.asa.physics.bean.Point;
import com.asa.physics.bean.ShiLiang;

/**
 * 经典物理
 * 这部分是以牛顿为根本的物理
 * 与近代物理不同，可能会混杂数学，而且这个里面的东西很多
 * 之后可能这个是个package，现在就先只是class了
 * 不过比较容易的是这个时间是不会变动的，相对论里面时间与运动有关真的醉人
 * @author Administrator
 *
 */
public class Norm {

	
	/*******************矢量。。。屎量**********************/
	/**
	 * 矢量这个其实可以看做是矩阵的降维运算
	 * 矩阵可以是多维的，而经典力学里面的是三维
	 */
	
	/**
	 * 求矢量的模长
	 * @param s1
	 * @return
	 */
	public static double shiliang_mo(ShiLiang s) {
		
		double[] xyz = s.xyz;
		double x = xyz[0];
		double y = xyz[0];
		double z = xyz[0];

		
		
		
		
		return Math.sqrt(x*x+y*y+z*z);
		
	}

	
	
	
	
	
	/**
	 * 加法
	 * @param s1
	 * @param s2
	 * @return
	 */
	public static ShiLiang shiliang_jiafa(ShiLiang s1,ShiLiang s2) {
		
		double[] a1 = s1.xyz;
		double[] b2 = s2.xyz;
		double[][] a = new double[1][0];
		double[][] b = new double[1][0];
		a[0] = a1;
		b[0] = b2;
		double[][] jiafa = MathHUtils.jiafa(a, b);
		
		ShiLiang result = new ShiLiang();
		result.xyz = new double[3];
		result.xyz = jiafa[0];
		
		return result;
	}
	/**
	 * 乘法	数量乘法
	 * @param u
	 * @param s1
	 * @return
	 */
	public static ShiLiang shiliang_chengfa(double u,ShiLiang s1) {
		
		double[] a1 = s1.xyz;
		double[][] a = new double[1][0];
		a[0] = a1;

		double[][] chenfa = MathHUtils.chenfa(a, u);
		ShiLiang result = new ShiLiang();
		result.xyz = new double[3];
		result.xyz = chenfa[0];
		
		return result;
	}
/**
 * 标量积	内积		这个值的模长等于0，则代表着垂直、正交
 * @param s1
 * @param s2
 * @return
 */
	public static double shiliang_biaoliangji(ShiLiang s1,ShiLiang s2) {
		
		double[] a1 = s1.xyz;
		double[] b2 = s2.xyz;
		double result = 0;
		for (int i = 0; i < b2.length; i++) {
			result += a1[i]*b2[i];
		}
		return result;
	}
	/**
	 * 矢量积	外积		这个值为0，则代表着平行
	 * @param s1
	 * @param s2
	 * @return
	 */
	public static ShiLiang shiliang_shiliangji(ShiLiang s1,ShiLiang s2) {
		
		double[] a1 = s1.xyz;
		double[] b2 = s2.xyz;
		ShiLiang result = new ShiLiang();
		result.xyz = new double[3];
		result.xyz[0] = a1[1]*b2[2] - b2[1]*a1[2];
		result.xyz[1] = a1[2]*b2[0] - b2[2]*a1[0];
		result.xyz[2] = a1[0]*b2[1] - b2[0]*a1[1];

		return result;
	}
	
	/**
	 * 一个将ABC三个矢量的矢量积求解的公式，其实直接算也行，这里算记忆一下吧
	 * @param s1
	 * @param s2
	 * @param s3
	 * @return
	 */
	public static ShiLiang shiliang_shiliangji(ShiLiang s1,ShiLiang s2,ShiLiang s3) {
		
		double ac = shiliang_biaoliangji(s1, s3);
		
		double ab = shiliang_biaoliangji(s1, s2);
		
		ShiLiang bac = shiliang_chengfa(ac, s2);

		ShiLiang cab = shiliang_chengfa(-ab, s3);
		
		ShiLiang result = shiliang_jiafa(bac, cab);
		
		return result;
	}

	
	/**
	 * 点到一个平面的距离
	 * @return
	 */
	public static double point2mian(Point p,double A,double B,double C,double D) {
		
		double d = Math.abs(A*p.x+B*p.y+C*p.z+D)/Math.sqrt(A*A+B*B+C*C);
		
		return d;
		
	}
	
	/*
	 * 两个平面夹角cos
	 */
	public static double mian2jiao(double A1,double B1,double C1,double D1,
			double A2,double B2,double C2,double D2) {
		double asa = (A1*A2+B1*B2+C1*C2)/(Math.sqrt(A1*A1+B1*B1+C1*C1)*Math.sqrt(A2*A2+B2*B2+C2*C2));
		return asa;
	}
	
	
	
	
	/**
	 * 点到直线的距离
	 * 直线的表达式有很多种，我选择这种，看上去和矩阵比较近，好计算
	 * @return
	 */
	public static double dian2xian(Point point,double A1,double B1,double C1,double D1,
			double A2,double B2,double C2,double D2) {
		ShiLiang n1 = new ShiLiang();
		ShiLiang n2 = new ShiLiang();

		n1.xyz= new double[]{A1,B1,C1};
		n2.xyz= new double[]{A2,B2,C2};	
		//得到这条直线上的一点
		double x = 1;
		double y = (D2*C1-C2*D1-C2*A1+C1*A2)/(C2*B1-C1*B2);
		double z = (A1+B1*y+D1)/(-C1);
		
		ShiLiang asb = shiliang_shiliangji(n1, n2);
		
		ShiLiang asc = new ShiLiang();

		asc.xyz= new double[]{point.x-x,point.y-y,point.z-z};
		
		
		ShiLiang shiliang_shiliangji = shiliang_shiliangji(asc, asb);
		
		double shiliang_mo = shiliang_mo(shiliang_shiliangji);
		double shiliang_mo2 = shiliang_mo(asb);
		
		return shiliang_mo/shiliang_mo2;
	}
	
	
	
	/*
	 * 空间中两直线的距离
	 * 这里的问题是混合积
	 * 
	 */
	public static double xian2xian(double A1,double B1,double C1,double D1,
			double A2,double B2,double C2,double D2,
			double A3,double B3,double C3,double D3,
			double A4,double B4,double C4,double D4) {
		
		ShiLiang n1 = new ShiLiang();
		ShiLiang n2 = new ShiLiang();
		n1.xyz= new double[]{A1,B1,C1};
		n2.xyz= new double[]{A2,B2,C2};	
		//得到这条直线上的一点
		double x1 = 1;
		double y1 = (D2*C1-C2*D1-C2*A1+C1*A2)/(C2*B1-C1*B2);
		double z1 = (A1+B1*y1+D1)/(-C1);
		ShiLiang v1 = shiliang_shiliangji(n1, n2);//直线1的向量
		
		
		
		ShiLiang n3 = new ShiLiang();
		ShiLiang n4 = new ShiLiang();
		n3.xyz= new double[]{A3,B3,C3};
		n4.xyz= new double[]{A4,B4,C4};	
		//得到这条直线上的一点
		double x2 = 1;
		double y2 = (D4*C3-C4*D3-C4*A3+C3*A4)/(C4*B3-C3*B4);
		double z2 = (A3+B3*y2+D3)/(-C3);
		ShiLiang v2 = shiliang_shiliangji(n3, n4);//直线1的向量
		
		
		
		ShiLiang asa = new ShiLiang();
		asa.xyz= new double[]{x2-x1,y2-y1,z2-z1};
		
		
		
		
		ShiLiang shiliang_shiliangji = shiliang_shiliangji(asa, v1);
		
		
		
		double shiliang_biaoliangji = shiliang_biaoliangji(shiliang_shiliangji,v2);
		ShiLiang asb = shiliang_shiliangji(v1, v2);
		double shiliang_mo = shiliang_mo(asb);
		
		
		
		return shiliang_biaoliangji/shiliang_mo;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	public static void main(String[] args) {
		
		ShiLiang s1 = new ShiLiang();
		ShiLiang s2 = new ShiLiang();
		s1.xyz = new double[] {1.,2.,3.};
		s2.xyz = new double[] {4.,5.,6.};

//		ShiLiang asa = shiliang_jiafa(s1, s2);
//		ShiLiang asa = shiliang_chengfa(2, s1);
		ShiLiang asa = shiliang_shiliangji(s1, s2);
		double[] xyz = asa.xyz;
		for (int i = 0; i < xyz.length; i++) {
			System.out.println(xyz[i]);
		}
		
		
		
		double asa2 = shiliang_biaoliangji(s1, s2);
		System.out.println(asa2);
		
		
		
	}
	
	
	
	
	
	
	
}
